iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 19
0

大綱

  • 附加事件處理器
  • 事件與狀態
  • 事件物件

附加事件處理器

在運作的過程中,React 會協助我們處理在 JavaScript 中看到的同樣事件:點擊事件的 MouseEvents,又或表單元素改變時的 Chang 事件,等等一些動作。這個時候事件的名稱和 JavaScript 中又會是相同的,並且觸發的條件也是相同的。這時候所謂的附加事件處理器的 React 語法就會和 HTML 語法十分類似。

事件與狀態

現在我們假設的情境是根據使用者輸入而做出改變,就好比問卷編輯器,它允許使用者從任何一個題目類型的選單中把問卷題目拖曳進來。

首先呢,我們從 render 函式開始,它註冊了一些基於 HTML5 的 Drag and Drop API 的事件處理器。

基於狀態的渲染:
在這裡,其中有一件事件處理器需要做的事情是擴充已經添加的題目清單。要做到這一點,我們會需要使用每一個 React 元件都有的內部狀態物件。它預設為空值 (null),但是可以透過元件的 getInitialState() 方法來初始化為可以使用的東西,像這樣:

getInitialState: function() {
  return {
    dropZoneEntered: false,
    title: ' ', introduction: ' ',
    questions: []
  };
}

這為我們的狀態建立了一條非常有意義的基線:空白的標題、空白的介紹、空白的題目清單、以及把 dropZoneEntered 的值設定為 false -- 以便指示使用者當前並未再拖放區放置任何東西。

更新狀態:
這裡要說明的是,由於在更新元件的內部狀態時會導致元件重新渲染,所以接下來我們的下一步要做的便是更新拖曳處理方法中的狀態。這個時候 render 便會再次執行,並且從 this.state 中讀取當前的值來顯示標題、介紹和題目。最後,使用者就會看到一切正確地更新了。

然後,我們有兩種方法可以更新元件的狀態:元件的 setState 方法和 replaceState 方法。replaceState 會用一個全新的狀態物件將舊的整個覆蓋掉,如果我們採用是不可變化的資料結構來保存我們元件的狀態,哪這個方法就會粉好用,不然的話,通常這也不會是我們要的。在這種情況下,更多的時候我們就會選擇使用 setState,哪這樣一來會單純地把我們提供的物件合併到原本的狀態物件。

以下,舉一個例子,我們來假設存在以下的狀態:

getInitialState: function() {
  return {
    dropZoneEntered: false,
    title: 'Fantastic Survey',
    introduction: 'This survey is fantastic!',
    question: [ ]
  };
}

在這種情況下,呼叫 this.setState({ title: ''Fantastic Survey 2.0'}),這只會影響到 this.state.title 的值,其餘的 this.state.dropZoneEntered、this.state.introduction 以及 this.state.question 是不會受到影響的。

另外,要特別說明的一點是永遠不要透過呼叫 setState 又或是 replaceState 以外的方法來改變狀態中的物件。像 this.state.saveInProgress = true 這樣的做法是很不好的,因為這會通知 React 進行重新渲染,可能會導致在下次呼叫 setState 時產生預期至外的結果,這會是不樂見的情況。

事件物件
在 React 中,我們擁有很多的處理器方法,對我來說只要能執行就能達到我們要的目的,但是,在某些時候我們會需要更多的關於使用者輸入的資訊來做處理及判斷。

React 的事件處理器函式總是傳遞事件物件,就像純 JavaScript 的事件監聽器一樣。舉一個例子,handleComplete 方法只接受一個事件物件,這個物件透過 event.target.value 從 textarea 中取得當前的值。哪...在事件處理器中我們使用了 event.target.value 是從表單輸入取得當前值的常見做法,特別是在 onChange 處理器當中。

最後,React 並不是直接把瀏覽器的 Event 物件傳給處理器,而是把原生的事件封裝到一個 SyntheticEvent 實作當中。SyntheticEvent 跟瀏覽器原生事件的外表和功能都是一樣的,除了增加了一些使跨瀏覽器運作更加平順的解決方案。我們也可以像使用一般事件一樣使用 SyntheticEvent,但是呢,如果今天是我們要用到瀏覽器的原生事件,我們就可以透過 SyntheticEvent 的 nativeEvent 欄位取得。


上一篇
[Day - 18] React 學習筆記 (三)
下一篇
[Day - 20] React 學習筆記 (五)
系列文
為自己而寫,前端工程師之 30 天心得分享30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言